所處公司的案例比較偏好能自行掌握服務,而非依賴像上一篇介紹的 Github 服務,由於公司相關服務使用了微軟全家桶,自然也將程式碼都放置在 Azure DevOps 上,不過是屬於地端的 Server 版。要連結 Azure DevOps 專案到 Backstage 可以透過官方內建的插件,但官方提供的只支援雲端的 Azure,而我們屬於地端就還需要依賴社群上的插件,對於這種混合使用插件的模式,值得一提。除了專案資訊,我們還需要查看到 CI/CD、Pull Requests 紀錄。
此專案是存放於 Azure DevOps Server (AzDevops) 的一個範例程式檔,專案位於組織的存儲庫下,並且擁有自定義網域來存取相關資源,與上一篇的 Github 專案大同小異,只是不再是掛在個人名下的空間。
現在要嘗試引入專案到 Backstage 中,以前面的基礎來看,我們可以採用註冊、靜態引入,首先嘗試直接將該 AzDevops 的專案網址貼入註冊組件,看看會發生什麼事情。
位於地端 AzDevops 的範例專案
直接將 AzDevops 的專案網址貼入註冊組件的結果
不意外的跳出錯誤,畢竟我們什麼設定都沒有動過,錯誤顯示的大意是「在 app-config.yaml
中的integrations
沒有發現對應的 host name。現在我們已經內建支援 github、Azure DevOps,可以嘗試看看直接貼入含有 catalog-info.yaml
的程式庫網址 (需注意的是,這邊預設提到的 Azure DevOps 通常是指雲端版的服務)。」
接下來我們順著他的提示來測試,直接在專案手動新增一個 app-config.yaml
檔案,並參照之前的範例檔案給定幾個基礎設定,然後將帶有該檔案路徑的網址貼到註冊組件當中。
出現 You may need to configure an integration for the target host
的錯誤,總和兩個結果,我們很明確的知道要加入什麼設定,由於這個模組在目前 Backstage 版本已經內建支援,不必再額外新增 import
,接下來參考官方文件的說明。
要整合 AzDevops 有三種驗證方式,只需要在 integrations
加入新的提供者 azure
,與之前我們設定的 Github 可以並存。
Using a service principal 使用服務主體:
integrations:
azure:
- host: dev.azure.com
credentials:
- clientId: ${AZURE_CLIENT_ID}
clientSecret: ${AZURE_CLIENT_SECRET}
tenantId: ${AZURE_TENANT_ID}
Using a managed identity 使用託管身分:
integrations:
azure:
- host: dev.azure.com
credentials:
- clientId: ${AZURE_CLIENT_ID}
Using a personal access token (PAT) 使用個人存取權杖 (PAT):
integrations:
azure:
- host: dev.azure.com
credentials:
- personalAccessToken: ${PERSONAL_ACCESS_TOKEN}
前述三種方式中,根據官方文件的註解說明:「You cannot use a service principal or managed identity for Azure DevOps Server (on-premises) organizations
」,由於我們使用的是自託管的 Azure DevOps Server (地端版本),僅能採用第三種方式,即個人存取權杖。前兩種方式則僅適用於雲端版本。在 AzDevops 右上角可以設定個人權杖,取得後連同上面的 integrations
第三種代碼一起貼入app-config.yaml
,存檔後就設定完成,讓我們再來測試一次。
申請個人權杖畫面
將 azure 相關設定貼入 app-config.yaml
重新測試第一個步驟,我們一樣直接貼入 AzDevops 的專案網址,這時可以發現可以讀到內容了!如果它偵測到我們的程式庫中沒有包含 app-config.yaml
,就會要求我們創建一個上去做 pull request,是不是跟上一篇操作 Github 一樣邏輯呢。
但是很遺憾,最後並不會新增成功。還記得之前我們為 Github 新增了身份驗證的 Auth 模組,同理在 AzDevops 這邊也會需要。但是問題來了,AzDevops 的 Auth 部分雖然官方也有提供相似功能,但是面臨與專案整合一樣預設只有相容雲端版,地端版要另外找解決方案。
因沒有對應的身份驗證服務而無法使用
由於這塊牽涉到的部分更為複雜,地端的服務也很可惜沒有像雲端版,可以使用內建的 OAuth 登入功能,以公司的使用情境我們使用的驗證方式基本上都是綁在 AD (Active Directory Domain Services ) 上,基於種種考量我們沒有繼續專研 Backstage 提供的 AzDevops 驗證方案,而是另外架設由 IdentityServer 為基礎做的 SSO (Single Sign-On),加上我們的營運架構不太允許我們有權限直接這樣控制…等等,所以我們決定採用靜態引入的方式,即是撰寫元文件檔案。
社群中也有人為了避免這類問題,撰寫了配合靜態引入的 AzDevops 插件。
我們最後找到了來自社群提供的插件,它是基於官方的 integrations.azure
為基礎 ,進行擴充功能的,這也是為什麼我們在前面進行了設定與測試,而不是直接使用這個擴充插件。
此插件主要有前、後端需要安裝,後端負責對自定義的地端 AzDevops 的相關 API 資料交換,前段則是讀取元文件檔案的指定專案,也另外支援看到該程式庫的 CI/CD、Pull request、Git Tag、Readme 檔案相關資訊。
前後端的 Github 頁面如下 :
@backstage-community/plugin-azure-devops
@backstage-community/plugin-azure-devops-backend
根目錄輸入指令安裝
yarn --cwd packages/backend add @backstage-community/plugin-azure-devops-backend
新增到 packages/backend/src/index.ts
backend.add(import('@backstage-community/plugin-azure-devops-backend'));
在 app-config.yaml
中新增 Azure DevOps 的服務主機與組織資訊。每個服務主機可以對應多個組織,若需進一步設定,也可以為特定主機使用不同的個人權杖。不過,目前我們僅使用一個權杖,且為了方便演示,該權杖已被設置為可讀取跨所有組織的資料,因此不需要示範多服務的配置。
azureDevOps:
host: [dev.azure.com](http://dev.azure.com/)
organization: my-company
需同時保留先前的 integrations.azure
設定
後端安裝並設定好後,我們可以使用啟用服務,並到後端該服務的網址檢查狀態,正常情況會回傳 ok 就代表我們安裝上沒有問題。至於為何是路徑 /health
,Backstage 在新增後湍插件開發時預設就會有這個路徑,用來方便檢測服務是正常狀態。
http://localhost:7007/api/azure-devops/health
根目錄輸入指令安裝
yarn --cwd packages/app add @backstage-community/plugin-azure-devops
在這邊直接新增了一個給 Azure DevOps 範例專案的設定檔,與前面加入設定檔的方式相同,最後也要記得把路徑引入到 app-config.yaml
。前面提到前端是用來讀取元數據檔案指定的專案,所以在這格設定檔中我們必須新增 annotations
在 metadata
底下,然後再新增以下的設定專案名稱/儲存庫名稱。
在 Backstage 中,annotations
是用來附加額外元數據到實體(如元件、API、資源等)的屬性,這些註釋通常以鍵值對的形式存在 :
dev.azure.com/project-repo: <project-name>/<repo-name>
---
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
name: azdevops_test
annotations:
dev.azure.com/project-repo: <project-name>/<repo-name>
spec:
type: website
lifecycle: experimental
owner: guests
system: demo
---
新增一個元數據檔案示範
接著再查看到 Catalog 目錄,這時我們已經成功加入 Azure DevOps 上的專案囉!但這個插件的功能還不止如此。
重新啟動服務後可以看到在 Catalog 目錄出現新的組件
這個擴充插件還支援了,可以顯示該程式庫的 CI/CD、Pull request、Git Tag、Readme 檔案這些資訊,要使用時我們只需要簡單引入,再加入packages/app/src/components/catalog/EntityPage.tsx
,來定義組件的內容頁面應該要顯示什麼,這邊打算以能夠看到該專案的 CI/CD 部署紀錄為目標。
import {
EntityAzurePipelinesContent,
EntityAzurePullRequestsContent,
EntityAzureGitTagsContent,
EntityAzureReadmeCard,
isAzureDevOpsAvailable,
} from '@backstage/plugin-azure-devops';
為了達到這個功能,我們只需引用其中 EntityAzurePipelinesContent
,而另一個是偵測如該組件有設定相關的 annotations
才會顯示這張卡片,我們可以很輕易的在 EntityPage 中找到對應的地方並加入以下設定。
// packages/app/src/components/catalog/EntityPage.tsx
import {
EntityAzurePipelinesContent,
isAzureDevOpsAvailable,
} from '@backstage-community/plugin-azure-devops';
const cicdContent = (
<EntitySwitch>
// ...
<EntitySwitch.Case if={isAzureDevOpsAvailable}>
<EntityAzurePipelinesContent defaultLimit={25} />
</EntitySwitch.Case>
// ...
</EntitySwitch>
加入完畢後,我們點擊該組件中的CI/CD
頁籤,這邊就能夠顯示出紀錄了,由於範例專案不會有資料,這邊就抓公司的案例來演示。
除了顯示 CI/CD 資訊,其他三種在設定上也是一樣方式,如果需要更詳細的說明請再參考該插件的文件。
Backstage 本身靈活的特性,在本篇以官方內建功能上的不足,再另由社群額外擴充開發,相互配合下來優化,同理當我們有自己的情境需求時,也可以自行擴充。但也是因為這樣的特性,在實務上會因為官方文件較舊或沒有提及現有的解決方案,又或是社群提供過多相似的插件功能,資訊分散不僅會引響開發進度,學習曲線也將更為艱難,透過我們演示的案例可以減少許多探索解決方案的時間,更快理解 Backstage 插件的開發風格與使用方式。
下一篇,連結了專案後,理所當然想到的是,如何控制特定人或組別才能看到專案呢?對於這種權限控管,首先要解決的是,如何對現有的公司人員進行身份驗證。
https://backstage.io/docs/integrations/azure/locations
https://github.com/backstage/community-plugins/tree/main/workspaces/azure-devops/plugins/azure-devops
https://github.com/backstage/community-plugins/tree/main/workspaces/azure-devops/plugins/azure-devops-backend